#include <X11/Xlib.h>
#include <X11/extensions/XShm.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <iostream>
#include <fstream>
#include <X11/Xutil.h>
#include <unistd.h>
#include <vector>
#include <string.h>
#include <chrono>
#include <csignal>
#include <thread>
#include <memory>
#include "IniFileParser.h"
#include "NetTools.h"
#include "SignalWraper.h"
#include <mutex>

class RemoteDesktopClient
{
private:
    Display *display;
    int display_client_fd, controller_client_fd;
    XImage *ximage;
    Window window;
    // GC gc;
    std::string ip;
    unsigned short display_port, controller_port;
    int width, height;
    pthread_t display_thread, event_thread, scale_thread;
    NetTools net_tools;
    std::mutex mtxWindowMutex;

    // SignalWraper signal_wraper;

    bool connectToDisplayServer();
    bool connectToControllerServer();
    void receiveImage();
    static void *startDisplayImage(void *arg);
    void captureXevent();
    static void *startCaptureXEvent(void *arg);
    // 反序列化字节流到XImage
    XImage *deserializeImage(const std::vector<char> &buffer, int src_width, int src_height);
    void scaleImageNearest(const XImage *src, XImage *dst);
    void scaleImageBilinear(const XImage *src, XImage *dst);
    unsigned long getPixel(const XImage *img, int x, int y);
    void scaleWindow();
    static void *startscaleWindow(void *arg);

public:
    RemoteDesktopClient(std::string ip, unsigned short display_port, unsigned short controller_port, int width, int height);

    ~RemoteDesktopClient();

    void start();
};